#include <stdio.h>
#include <assert.h>

int gcd(int m, int n);

int main(int argc, char **argv){
    printf("Testing gcd function with assert...\n");

    // Test cases for non-negative inputs

    // Base case: gcd(m, 0) == m
    printf("Testing gcd(10, 0)...\n");
    assert(gcd(10, 0) == 10);
    printf("gcd(10, 0) test passed.\n");

    // Base case: gcd(0, m) == m (where m > 0)
    printf("Testing gcd(0, 10)...\n");
    assert(gcd(0, 10) == 10); // gcd(0, 10) -> gcd(10, 0%10) -> gcd(10, 0) -> 10
    printf("gcd(0, 10) test passed.\n");

    // Edge case: gcd(0, 0) == 0 according to THIS implementation (0%0 is undefined,
    // but the if(n==0) catches it first). Mathematically often undefined or 0.
    printf("Testing gcd(0, 0)...\n");
    assert(gcd(0, 0) == 0); // gcd(0, 0) -> n==0 is true -> returns m (0)
    printf("gcd(0, 0) test passed.\n");


    // Case: one number is a multiple of the other
    printf("Testing gcd(10, 5)...\n");
    assert(gcd(10, 5) == 5);
    printf("gcd(10, 5) test passed.\n");

    printf("Testing gcd(5, 10)...\n");
    assert(gcd(5, 10) == 5);
    printf("gcd(5, 10) test passed.\n");

    // Case: relatively prime numbers (GCD is 1)
    printf("Testing gcd(7, 5)...\n");
    assert(gcd(7, 5) == 1);
    printf("gcd(7, 5) test passed.\n");

    printf("Testing gcd(15, 8)...\n");
    assert(gcd(15, 8) == 1);
    printf("gcd(15, 8) test passed.\n");

    // Case: numbers with common factors > 1
    printf("Testing gcd(12, 18)...\n");
    assert(gcd(12, 18) == 6);
    printf("gcd(12, 18) test passed.\n");

    printf("Testing gcd(18, 12)...\n");
    assert(gcd(18, 12) == 6);
    printf("gcd(18, 12) test passed.\n");

    printf("Testing gcd(100, 75)...\n");
    assert(gcd(100, 75) == 25);
    printf("gcd(100, 75) test passed.\n");

    printf("Testing gcd(48, 18)...\n"); // gcd(48,18) -> gcd(18, 48%18=12) -> gcd(12, 18%12=6) -> gcd(6, 12%6=0) -> 6
    assert(gcd(48, 18) == 6);
    printf("gcd(48, 18) test passed.\n");


    printf("\nAll assert tests passed for gcd function (primarily non-negative cases).\n");

    return 0;
}

/**
 * Program 5.3 Euclid’s algorithm
 * One of the oldest-known algorithms, dating back over 2000 years,
 * is this recursive method for finding the greatest common divisors of two integers.
 */
int gcd(int m, int n){
    if (n == 0) {
        return m;
    }
    return gcd(n, m%n);
}
